package com.dean.db.service;

import com.dean.batch.entity.BaseEntity;
import com.dean.constants.DeanUiConstants;
import com.dean.entity.DeanDbConnInfo;
import com.dean.entity.SysDbConnInfo;
import com.dean.utils.DeanJdbcUtils;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class DbServiceEnhance<T extends BaseEntity> {
    public DbService<T> getDbService(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(DbServiceImpl.class);
        enhancer.setCallback(new ConnCloseMethodInterceptor());
        DbService<T> dbService = (DbServiceImpl<T>) enhancer.create();
        return dbService;
    }
}

class ConnCloseMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) {
        String methodName = method.getName();
        // 获取传入参数 第一个参数为数据库连接信息
        SysDbConnInfo connInfo = (SysDbConnInfo) objects[0];
        // 第二个参数为 sql语句
        String sql = (String) objects[1];
        // 第三个参数为sql执行参数
        String [] params = (String[]) objects[objects.length-1];
        // 获取数据连接
        Connection connection = null;
        // 获取执行器
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        Object obj =null;
        try{
            connection = DeanJdbcUtils.getConnection(connInfo);
            statement = DeanJdbcUtils.getPreparedStatement(connection,sql);
            // 设置参数
            objects[2] = statement;

            // 设置执行参数
            for (int i = 0; i < params.length; i++) {
                String param = params[i];
                statement.setString(i+1, param);
            }
            // 查询的处理
            if(methodName.startsWith(DeanUiConstants.QUERY_CHAR)){
                resultSet = statement.executeQuery();
                objects[2] = resultSet;
            }
            obj = methodProxy.invokeSuper(o,objects);
        }catch (Throwable throwable){
            throwable.printStackTrace();
        }finally {
            DeanJdbcUtils.close(resultSet,statement,connection);
        }
        return obj;
    }
}
